<p>When building a <a href="https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api">REST API</a>, <a
href="https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-8.0#attribute-routing-with-http-verb-attributes">it’s
recommended</a> to annotate the controller actions with the available <a
href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.routing.httpmethodattribute">HTTP attributes</a> to be precise about what
your API supports.</p>
<h2>Why is this an issue?</h2>
<ul>
  <li> <strong>Ambiguity</strong>: Without HttpAttributes, it’s unclear which HTTP methods an action method should respond to. This can lead to
  confusion and make the code harder to understand and maintain. </li>
  <li> <strong>Unsupported HTTP Methods</strong>: If an action is not annotated at all or is annotated only with the <a
  href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.routeattribute">Route attribute</a>, it accepts all HTTP methods even if
  they are not supported by that action, which leads to further confusion. </li>
  <li> <strong>Problems with Swagger</strong>: <a
  href="https://learn.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger">Swagger</a> relies on HttpAttributes to generate
  parts of the API documentation. These attributes are necessary for the generated documentation to be complete. </li>
  <li> <strong>Route path conflicts</strong>: Without HttpAttributes, it’s possible to accidentally create action methods that respond to the same
  route and HTTP method. This can lead to unexpected behavior and hard-to-diagnose bugs. </li>
  <li> <strong>Lack of routing flexibility</strong>: The HTTP attributes allow you to define multiple action methods in the same controller that
  respond to the same route but different HTTP methods. If you don’t use them, you might have limited flexibility when designing your API. </li>
</ul>
<h2>How to fix it</h2>
<p>You should annotate the controller actions with the available HttpMethod attributes. You can still use them in conjunction with the Route
attribute, in case there are multiple templates for one action and you need to <a
href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.routeattribute.order?view=aspnetcore-8.0">set the order</a>. This allows
you to clearly define the HTTP methods each action method should respond to, while still being able to customize your routes.</p>
<h2>Exceptions</h2>
<p>This rule does not raise if the controller or the action is annotated with <code>[<a
href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.apiexplorersettingsattribute">ApiExplorerSettings</a>(IgnoreApi =
true)]</code> or <a href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.acceptverbsattribute"><code>AcceptsVerbs</code>
attribute</a>.</p>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
[Route("Customer")]                                                        // This route conflicts with GetCustomers action route
public async Task&lt;IResult&gt; ChangeCustomer([FromBody] CustomerData data)   // Noncompliant
{
    // ...
    return Results.Ok();
}

[Route("Customer")]                         // This route conflicts with ChangeCustomer action route
public async Task&lt;string&gt; GetCustomers()    // Noncompliant
{
    return _customerRepository.GetAll();
}
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="1" data-diff-type="compliant">
[Route("Customer")]
[HttpPost]
public async Task&lt;IResult&gt; ChangeCustomer([FromBody] CustomerData data)    // Compliant
{
    // ...
    return Results.Ok();
}

[HttpGet("Customer")]
public async Task&lt;string&gt; GetCustomers()    // Compliant
{
    return _customerRepository.GetAll();
}
</pre>
<h2>Resources</h2>
<h3>Documentation</h3>
<ul>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing">Routing to controller actions in ASP.NET
  Core</a> </li>
  <li> Microsoft Learn - <a
  href="https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing#attribute-routing-with-http-verb-attributes">Attribute routing with Http
  verb attributes</a> </li>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle">Get started with
  Swashbuckle and ASP.NET Core</a> </li>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/aspnet/core/web-api/handle-errors#exception-handler">ASP.NET Core Exception
  handler</a> </li>
  <li> Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.routeattribute">RouteAttribute Class</a> </li>
</ul>

